/************************************************************
   Copyright 2008 Abhinav Pobbati

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*************************************************************/

#pragma once

#pragma unmanaged
#include <Common/Base/Math/Matrix/hkMatrix3.h>
#include <Common/Base/Math/Matrix/hkRotation.h>
#include <Common/Base/Math/Matrix/hkTransform.h>
#pragma managed

namespace Havok4Xna {

	ref class HkVector4;
	ref class HkRotation;
	ref class HkTransform;
	ref class HkQsTransform;
	ref class HkQuaternion;

	public ref class HkMatrix3 : public INativeReference {
	public:
		/// <summary>Copy matrix from the specified matrix.</summary>
		HkMatrix3(HkMatrix3 ^mat);
		
		/// <summary>Empty constructor. The elements of the matrix are not initialized.</summary>
		HkMatrix3();

		/// <summary> Get the element at the specified row and column. </summary>
		float Get(int row, int col);

		/// <summary> Set the element at the specified row and column. </summary>
		void Set(int row, int col, float value);

		/// <summary> Sets all rows at once. </summary>
		void SetRows(HkVector4 ^v0, HkVector4 ^v1, HkVector4 ^v2);

		/// <summary> Sets all columns of the current matrix. Where column is set to r0 and so on. </summary>
		void SetCols(HkVector4 ^v0, HkVector4 ^v1, HkVector4 ^v2);
		void SetZero();
		void SetDiagonal(float m00, float m11, float m22);
		void SetIdentity();
		bool IsApproximatelyEqual(HkMatrix3 ^m, float epsilon);
		void SetCrossSkewSymmetric(HkVector4 ^v);
		HkResult Invert(float epsilon);
		void InvertSymmetric();
		void Transpose();
		void SetTranspose(HkMatrix3 ^mat);
		void SetMul(HkMatrix3 ^a, HkMatrix3 ^b);
		void SetMulInverse(HkMatrix3 ^a, HkRotation ^r);
		void SetMul(float scale, HkMatrix3 ^m);
		void AddMul(float scale, HkMatrix3 ^m);
		void ChangeBasis(HkRotation ^r);
		void Add(HkMatrix3 ^m);
		void Sub(HkMatrix3 ^m);
		void Mul(HkMatrix3 ^m);
		void Mul(float scale);
		bool IsOk();

	internal:
		HK_CLASS_INTERNALS(HkMatrix3,hkMatrix3)
	};

	public ref class HkRotation : public HkMatrix3 {
	public:
		HkRotation();

		void Set(HkQuaternion ^q);
		void SetAxisAngle(HkVector4 ^v, float angle);
		bool IsOrthonormal(float epsilon);
		void Renormalize();

	internal:
		HK_DERIVED_CLASS_INTERNALS(HkRotation,hkRotation,HkMatrix3)
	};
}
